package personal.lijun.skeleton.springcloud.serviceprovider.service.impl;

import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import personal.lijun.skeleton.spring.springcloud.serviceprovider.data.*;
import personal.lijun.skeleton.spring.springcloud.serviceprovider.service.ResourceService;
import personal.lijun.skeleton.springcloud.common.data.CommonExample;
import personal.lijun.skeleton.springcloud.dataaccess.dao.ResourcePermissionMapper;
import personal.lijun.skeleton.springcloud.dataaccess.dao.SysResourceMapper;
import personal.lijun.skeleton.springcloud.dataaccess.data.SysResource;
import personal.lijun.skeleton.springcloud.dataaccess.data.SysResourceExample;
import personal.lijun.skeleton.springcloud.dataaccess.data.SysRouter;
import personal.lijun.skeleton.springcloud.utils.validate.ParamValid;
import personal.lijun.skeleton.springcloud.utils.validate.ValidGroups;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Auther: lijun@sstcsoft.com
 * @Date: 2019-10-10 17:40
 */
@Service("resourceService")
public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private SysResourceMapper sysResourceMapper;

    @Autowired
    private ResourcePermissionMapper resourcePermissionMapper;
    /**
     * 得到所有可用的资源
     *
     * @return
     */
    @Override

    public List<AvailableResource> listAllAvailable() {
        SysResourceExample sysResourceExample = new SysResourceExample();
        SysResourceExample.Criteria criteria = sysResourceExample.createCriteria();
        criteria.andIsLockedEqualTo(false);
        List<SysResource> sysResourceList = sysResourceMapper.selectByExample(sysResourceExample);
        List<AvailableResource> availableResources = new ArrayList<>(sysResourceList.size());
        SysResource sysResource;
        AvailableResource availableResource;
        for(int i=0;i<sysResourceList.size();i++){
            availableResource = new AvailableResource();
            sysResource = sysResourceList.get(i);
            BeanUtils.copyProperties(sysResource,availableResource);
            availableResource.setRouterId(sysResource.getRouter()!=null?sysResource.getRouter().getId():(Integer) null);
            availableResources.add(availableResource);
        }
        return availableResources;
    }

    /**
     * 得到用户授权的资源
     *
     * @param userId 用户Id
     * @return
     */
    @Override
    public List<Resource> listAuthorizedByUserId(int userId) {
        CommonExample example = new CommonExample();
        CommonExample.Criteria criteria = example.createCriteria();
        criteria.andFieldEqualTo(false,"result.is_locked");
        criteria.andFieldEqualTo(userId,"ur.user_id");
        List<SysResource> sysResourceList = sysResourceMapper.listAuthorized(example);
        return sysResourceList.stream().map(sysResource -> transformSysResource2Resource(sysResource)).collect(Collectors.toList());
    }

    private Resource transformSysResource2Resource(SysResource sysResource){
        Resource resource = new Resource();
        BeanUtils.copyProperties(sysResource,resource);
        SysRouter sysRouter = sysResource.getRouter();
        if(sysRouter != null){
            Router router = new Router();
            BeanUtils.copyProperties(sysRouter,router);
            resource.setRouter(router);
            resource.setRouterId(router.getId());
        }
        return resource;
    }
    /**
     * 根据路由id得到资源列表
     *
     * @param routerId
     * @return
     */
    @Override
    public List<Resource> listByRouterId(int routerId) {
        CommonExample example = new CommonExample();
        CommonExample.Criteria criteria = example.createCriteria();
        criteria.andFieldEqualTo(routerId,"r1.router_id");
        List<SysResource> sysResourceList = sysResourceMapper.listRelationRouter(example);
        return sysResourceList.stream().map(sysResource -> transformSysResource2Resource(sysResource)).collect(Collectors.toList());
    }

    /**
     * 根据id得到资源
     *
     * @param id
     * @return
     */
    @Override
    public Resource getById(int id) {
        CommonExample example = new CommonExample();
        CommonExample.Criteria criteria = example.createCriteria();
        criteria.andFieldEqualTo(id,"r1.id");
        List<SysResource> sysResourceList = sysResourceMapper.listRelationRouter(example);
        List<Resource> resourceList = sysResourceList.stream().map(sysResource -> transformSysResource2Resource(sysResource)).collect(Collectors.toList());
        if(resourceList.size()>1)
            throw new TooManyResultsException();
        else if(resourceList.size() == 0)
            return null;
        else
            return resourceList.get(0);
    }

    /**
     * 添加资源
     *
     * @param dto
     * @return 新增资源的主键值
     */
    @Override
    @ParamValid
    public int saveResource(@ValidGroups(groups = {Resource.INSERT_GROUP.class})Resource dto) {
        SysResource sysResource = new SysResource();
        BeanUtils.copyProperties(dto,sysResource);
        int rows = sysResourceMapper.insertSelective(sysResource);
        dto.setId(sysResource.getId());
        return rows;
    }

    /**
     * 更新资源
     *
     * @param dto
     * @return 数据库中受影响的行数
     */
    @Override
    @ParamValid
    public int updateResource(@ValidGroups(groups = {Resource.UPDATE_GROUP.class})Resource dto) {
        SysResource sysResource = new SysResource();
        BeanUtils.copyProperties(dto,sysResource);
        return sysResourceMapper.updateByPrimaryKeySelective(sysResource);
    }

    /**
     * 删除资源
     *
     * @param id
     * @return 数据库中受影响的行数
     */
    @Override
    public int removeResource(int id) {
        return sysResourceMapper.deleteByPrimaryKey(((Integer)id).shortValue());
    }

    /**
     * 得到用户资源权限
     *
     * @param userId 用户Id
     * @return
     */
    @Override
    public List<Resource> listPermissionByUserId(int userId) {
        List<SysResource>  sysResourceList = resourcePermissionMapper.listByUserId(userId);
        return sysResourceList.stream().map(sysResource -> transformSysResource2Resource(sysResource)).collect(Collectors.toList());
    }

    /**
     * 根据路由id得到资源权限
     *
     * @param userId
     * @param routerId
     * @return
     */
    @Override
    public List<ResourcePermission> listPermission(int userId, int routerId) {
        List<SysResource>  sysResourceList = resourcePermissionMapper.listPermission(userId,routerId);
        return sysResourceList.stream().map(sysResource -> transformSysResource2ResourcePermission(sysResource)).collect(Collectors.toList());
    }

    private ResourcePermission transformSysResource2ResourcePermission(SysResource resource){
        ResourcePermission resourcePermission = new ResourcePermission();
        resourcePermission.setResourceId(resource.getId());
        resourcePermission.setResourcePermission(resource.getPermission());
        return resourcePermission;
    }
    /**
     * 得到用户资源权限代码
     *
     * @param userId 用户Id
     * @return
     */
    @Override
    public List<String> listPermissionCodeByUserId(int userId) {
        return resourcePermissionMapper.listCodeByUserId(userId);
    }
}
